// 类型守卫

// 1.类型收缩 | 类型收窄
// typeof 是有缺陷的  比如说 数组 对象  函数  null 它都返回object
const isString = (str:any) => typeof str === "string"

const isArr = (arr:any) => arr instanceof Array

// 2.类型谓词 | 自定义守卫
// 实现一个函数，该函数可以传入任何类型
// 但是如果是object 就检查里面的属性，
// 如果里面的属性是number就取两位小数
// 如果是string就去除左右空格
// 如果是函数就执行

// 1.发现没有任何代码提示  原因是any类型
// 自定义守卫 它只能接收布尔值
// 语法规则  参数  is 类型
// 这个函数如果返回true 就返回true
// 如果返回false 就返回false
// 如果返回undefined 就返回undefined那么这个参数就是你想要的类型

// 2.properties of undefined (reading 'a')
// nodejs环境this成了undefined
// 浏览器环境this指向window 函数独立调用指向window

// const isObj = (arg: any) => Object.prototype.toString.call(arg) === "[object Object]"
const isObj = (arg: any) => ({}).toString.call(arg) === "[object Object]"
const isNum = (num:any):num is number => typeof num=== 'number'
const isStr = (str:any):str is string => typeof str === 'string'
const isFn = (fn:any):fn is Function => typeof fn === 'function'


const typeGuardFn = (data:any) => {
  if(isObj(data)) {
    let val;
    // 遍历数学不能用for in 因为for in 它会遍历原型链上的属性
    Object.keys(data).forEach(key => {
      val = data[key]
      if(isNum(val)) {
        data[key] = val.toFixed(2)
      } else if(isStr(val)) {
        data[key] = val.trim()
      } else if(isFn(val)) {
        data[key]()
      }
    })
  }
}

let objTypeGuard = {
  name: '   zhangsan   ',
  num: 18.6565656,
  sex: '男',
  fn: () => {
    console.log('fn', objTypeGuard)
  },
  c: function() {
    console.log('c', this)
    return this.name
  }
}

typeGuardFn(objTypeGuard)